package com.zzb.codegenerator.generator;

import com.zzb.codegenerator.bean.ProjectMeta;
import com.zzb.codegenerator.bean.TableMeta;
import com.zzb.codegenerator.config.GeneratorConfig;
import com.zzb.codegenerator.generator.connect.ConnectPool;
import com.zzb.codegenerator.generator.context.TableMetaContext;
import com.zzb.codegenerator.generator.folder.MkdirUtils;
import com.zzb.codegenerator.generator.table.TableMetaFactoryBean;
import com.zzb.codegenerator.utils.Misc;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 写文件生成器
 */
public class FreeMarkerGenerator implements IGenerator {
    //freemarker配置
    private Configuration freeMarkerCfg = new Configuration(Configuration.VERSION_2_3_23);

    /**
     * 初始化freemarker配置
     *
     * @throws Exception
     */
    private void initFreeMarkerCfg(GeneratorConfig config) throws Exception {
        //获取当前class目录
        String templatePath = config.getTemplateDir();
        if(StringUtils.isBlank(templatePath)){
        	templatePath=System.getProperty("user.dir")+"\\simple\\template";
        	config.setTemplateDir(templatePath);
        }
        
        File file = new File(templatePath);
        if (!file.exists()) {
            throw new Exception("没有模板文件");
        }

        freeMarkerCfg.setDirectoryForTemplateLoading(new File(templatePath));
        freeMarkerCfg.setDefaultEncoding("UTF-8");
        freeMarkerCfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
    }

    /**根据ProjectMeta生成文档*/
    private void generatorFiles(ProjectMeta projectMeta){
        List<String> templateFiles = Misc.getSimpleFilenames(projectMeta.getGeneratorConfig().getTemplateDir());
        if(CollectionUtils.isNotEmpty(templateFiles)){
            templateFiles.forEach(templateFile -> {
                try {
                    generatorFile(projectMeta, templateFile);
                } catch (Exception e) {
                    System.err.println("根据["+templateFile+"]生成文件失败["+projectMeta.getTableMeta().getBeanName()+"]："+e.getMessage());
                }
            });
        }
    }

    /**根据ProjectMeta和模板文件名生成文档*/
    private void generatorFile(ProjectMeta projectMeta,String templateFile) throws Exception {
        GeneratorConfig config = projectMeta.getGeneratorConfig();
        TableMeta tableMeta = projectMeta.getTableMeta();
        String OUT_PARRENT = config.getOutFilePattern();
        //获取Template
        Template template = freeMarkerCfg.getTemplate(templateFile);
        //输出文件地址
        String outFilePath = config.getSaveDir() ;
        File foutFilePath = new File(outFilePath);
        //创建dao文件夹
        if (!foutFilePath.exists() && !foutFilePath.isFile()) {
            boolean mkdir = foutFilePath.mkdir();
            if(!mkdir)
                throw new Exception("ERROR-创建" + outFilePath + "文件夹失败" );
        } else if (foutFilePath.isFile()) {
            throw new Exception("ERROR-创建" + outFilePath + "文件夹失败，" + outFilePath + "不能为文件");
        }
        //临时文件地址
        String tmpFilePath = outFilePath+File.separator + templateFile + ".tmp";
        File tmpFile = new File(tmpFilePath);
        if (tmpFile.exists()) {
            boolean delete = tmpFile.delete();
            if(!delete){
                System.err.println("WARN-删除临时文件出错");
            }
        }
        //OutputStreamWriter writer = new OutputStreamWriter(System.out, "UTF-8");
        OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tmpFilePath), "UTF-8");
        Map<String, Object> root = new HashMap<>();
        root.put("root", tableMeta);
        root.put("config",config);
        template.process(root, writer);
        writer.flush();
        writer.close();

        //读取临时文件，并写新文件
        tmpFile = new File(tmpFilePath);
        FileInputStream src = new FileInputStream(tmpFile);
        InputStreamReader ir = new InputStreamReader(src);
        BufferedReader br = new BufferedReader(ir);
        //第一行是文件地址信息
        String outStr = br.readLine();
        StringBuilder fileStr = new StringBuilder();
        String savePath = config.getSaveDir() + File.separator + tableMeta.getBeanName() + templateFile;
        if ((outStr.contains(OUT_PARRENT))) {
            savePath = config.getSavePath() + File.separator + outStr.substring(OUT_PARRENT.length());
        }else{
            fileStr.append(outStr);
        }

        String tmpStr;
        while((tmpStr=br.readLine())!=null)fileStr.append(tmpStr).append("\r\n");
        br.close();
        ir.close();
        src.close();
        //删除临时文件
        tmpFile.delete();

        //写输出文件
        File outFile = new File(savePath);
        if(outFile.exists() ){
            outFile.delete();
        }
        System.out.println("输出文件："+savePath);

        File outDirect = new File(savePath).getParentFile();
        if(!outDirect.exists() && !outDirect.isFile()){
            outDirect.mkdirs();
        }

        writer = new OutputStreamWriter(new FileOutputStream(savePath), "UTF-8");
        writer.write(fileStr.toString());
        writer.flush();
        writer.close();

    }

    @Override
    public void generator(GeneratorConfig config,List<ProjectMeta> projectMetas) {
        try {
            //创建文件夹
            if (!MkdirUtils.makeDir(config)) return;
            //初始化freemarker
            initFreeMarkerCfg(config);
            if(CollectionUtils.isNotEmpty(projectMetas)){
                projectMetas.forEach(this::generatorFiles);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("生成失败！");
        }
    }


}
